home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / ucrasm27.zip / SOURCE.ZIP / APPENDM.ASM < prev    next >
Assembly Source File  |  1992-03-13  |  4KB  |  209 lines

  1.  
  2. ; Need to include "lists.a" in order to get list structure definition.
  3.  
  4.         include    lists.a
  5.         extrn    sl_malloc:far
  6.  
  7.  
  8. wp        equ    <word ptr>        ;I'm a lazy typist
  9.  
  10.  
  11. ; Special case to handle MASM 6.0 vs. all other assemblers:
  12. ; If not MASM 5.1 or MASM 6.0, set the version to 5.00:
  13.  
  14.         ifndef    @version
  15. @version    equ    500
  16.         endif
  17.  
  18.  
  19.  
  20. StdGrp        group    stdlib,stddata
  21. stddata        segment    para public 'sldata'
  22. stddata        ends
  23.  
  24. stdlib        segment    para public 'slcode'
  25.         assume    cs:stdgrp
  26.  
  27.  
  28. ; sl_Appendm-    DX:SI points at a block of data bytes.
  29. ;        ES:DI points at a list.
  30. ;        CX contains the node number to append the new node after.
  31. ;
  32. ;        This routine allocates storage for a new node on the
  33. ;        heap, copies the data from DX:SI to the new node,
  34. ;        and then links in the new node to the list after
  35. ;        the CXth node.
  36. ;
  37. ;        Returns the carry set if memory allocation error
  38. ;        occurs.
  39. ;
  40. ; Randall Hyde  3/13/92
  41.  
  42.  
  43.         public    sl_Appendm
  44. sl_Appendm    proc    far
  45.         pushf
  46.         push    ds
  47.         push    ax
  48.         push    bx
  49.         push    cx
  50.         push    dx
  51.         push    si
  52.         push    es
  53.         push    di
  54.         cld
  55.  
  56.  
  57.  
  58.         if    @version ge 600
  59.  
  60. ; MASM 6.0 version goes here
  61.  
  62.         mov    ds, dx
  63.         mov    dx, cx            ;Save for later
  64.  
  65. ; First, allocate storage for the new node:
  66.  
  67.         mov    cx, es:[di].List.ListSize
  68.         push    cx            ;Save for later
  69.         add    cx, size NODE        ;Add in overhead
  70.         call    sl_malloc        ;Go get the memory
  71.         pop    cx            ;Get real length back.
  72.         jc    BadAppend        ;If malloc error
  73.         push    di            ;Save ptr to new NODE.
  74.  
  75. ; Compute offset to actual data area (skipping over list pointers, etc.)
  76.  
  77.         add    di, size Node
  78.  
  79.  
  80.     rep    movsb                ;Copy the node's data.
  81.         pop    si            ;Get ptr to original node
  82.         mov    cx, es            ;Make ds:si point at node.
  83.         mov    ds, cx
  84.         pop    di            ;Get ptr to list var
  85.         pop    es
  86.         push    es
  87.         push    di
  88.  
  89. ; At this point, DS:SI points at the new node on the heap and ES:DI points
  90. ; at the list variable.
  91.  
  92. ; See if the the list is empty:
  93.  
  94.         cmp    wp es:[di].List.Head+2, 0
  95.         jne    GetTheNode
  96.  
  97. ; If this is an empty list (list is empty if HEAD is NIL), then build the
  98. ; list from this single node.
  99.  
  100.         mov    wp es:[di].List.Tail, si
  101.         mov     wp es:[di].List.Head, si
  102.         mov    wp es:[di].List.CurrentNode, si
  103.         mov    wp es:[di].List.Tail+2, ds
  104.         mov    wp es:[di].List.Head+2, ds
  105.         mov    wp es:[di].List.CurrentNode+2, ds
  106.  
  107. ; Set the link fields of this new node to NIL.
  108.  
  109.         mov    wp [si].Node.Next, 0
  110.         mov    wp [si].Node.Prev, 0
  111.         mov    wp [si].Node.Next+2, 0
  112.         mov    wp [si].Node.Prev+2, 0
  113.  
  114.         pop    di
  115.         pop    es
  116.         jmp    GoodAppend
  117.  
  118.  
  119. ; If the list has some nodes, locate the CXth node down here (or locate
  120. ; the last node if there are more than CX nodes in the list).
  121.  
  122. GetTheNode:    mov    cx, dx            ;Retrieve node count.
  123.         les    di, es:[di].List.Head        ;Get ptr to first node
  124.         jmp    short IntoLoop
  125.  
  126. ; The following loop repeats until we reach the end of the list or we count
  127. ; off CX nodes in the list.
  128.  
  129. FindNode:    les    di, es:[di].Node.Next
  130. IntoLoop:    cmp    dx, wp es:[di].Node.Next
  131.         loopne    FindNode
  132.  
  133.  
  134. ;If there were items in the list, perform the insert down here.
  135.  
  136.         les    di, es:[di].List.CurrentNode    ;Get ptr to item
  137.         mov    ax, wp es:[di].Node.Next    ;Get ptr to next
  138.         mov    bx, wp es:[di].Node.Next+2    ; node and save.
  139.  
  140. ; Use the address of CurrentNode as the previous ptr for the new node.
  141.  
  142.         mov    wp ds:[si].Node.Prev, di     ;Patch in link
  143.         mov    wp ds:[si].Node.Prev+2, es
  144.  
  145. ; Okay, store the new node's address into the NEXT field of the current node
  146.  
  147.         mov    wp es:[di].Node.Next, si    ;Patch in fwd ptr
  148.         mov    wp es:[di].Node.Next+2, ds
  149.  
  150. ; Set the NEXT field of the new node to the original previous node.
  151.  
  152.         mov    wp ds:[si].Node.Next, ax
  153.         mov    wp ds:[si].Node.Next+2, bx
  154.  
  155. ; Patch in the Prev field of the original NEXT node:
  156.  
  157.         mov    es, bx
  158.         mov    di, ax
  159.         mov    wp es:[di].Node.Prev, si
  160.         mov    wp es:[di].Node.Prev+2, ds
  161.  
  162. ; Set the CurrentNode ptr to the new node
  163.  
  164.         pop    di            ;Retrive ptr to list var.
  165.         pop    es
  166.         mov    wp es:[di].List.CurrentNode, si
  167.         mov    wp es:[di].List.CurrentNode+2, ds
  168.  
  169.  
  170.  
  171.  
  172.  
  173.         else
  174.  
  175. ; All other assemblers come down here:
  176.  
  177.  
  178.  
  179.         endif
  180.  
  181. ; DANGER WILL ROBINSON! Multiple exit points.  Be wary of these if you
  182. ; change the way things are pushed on the stack.
  183.  
  184. GoodAppend:    pop    si
  185.         pop    dx
  186.         pop    cx
  187.         pop    bx
  188.         pop    ax
  189.         pop    ds
  190.         popf
  191.         clc
  192.         ret
  193.  
  194. BadAppend:    pop    di
  195.         pop    es
  196.         pop    si
  197.         pop    dx
  198.         pop    cx
  199.         pop    bx
  200.         pop    ax
  201.         pop    ds
  202.         popf
  203.         stc
  204.         ret
  205. sl_Appendm    endp
  206.  
  207. stdlib        ends
  208.         end
  209.